package self.hoy.demo.grainmall.auth.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import self.hoy.demo.common.constant.AuthServerConstant;
import self.hoy.demo.common.to.MemberTo;
import self.hoy.demo.common.to.auth.WeiboUserDetail;
import self.hoy.demo.common.utils.HttpUtils;
import self.hoy.demo.common.utils.R;
import self.hoy.demo.common.to.auth.WeiboUser;
import self.hoy.demo.grainmall.auth.feign.MemberFeignService;

import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;


/**
 * oauth 2.0 授权登录
 * @author hyh
 * @date 2020/8/13
 */
@Slf4j
@Controller
@RequestMapping("/oauth")
public class AuthController {

    /**
     * 参数来源：
     * https://open.weibo.com/apps/xxxxx/info/basic 其中xxxxx是每个人的uid
     */
    @Value("${weibo.app-key}")
    private String appKey;

    @Value("${weibo.app-secret}")
    private String appSecret;

    @Autowired
    private MemberFeignService memberFeignService;

    /**
     * 获取微博社交登录接口所需数据
     * @return
     */
    @PostMapping("/weibo")
    @ResponseBody
    public R weiboAuthInfo() {
        // 前往微博授权页面
        String authUrl = "https://api.weibo.com/oauth2/authorize?client_id="
                + appKey + "&response_type=code&redirect_uri="
                + "http://auth.grainmall.cn/oauth/weibo/success";

        // 用户同意授权则跳转至 http://grainmall.cn/success?code=xxxxxx
        return R.ok().put("url", authUrl);
    }

    /**
     * 微博授权登录后，携带code参数回调这个地址
     * 然后用code获取/换取 access_token
     * API 文档 https://open.weibo.com/wiki/Oauth2/access_token
     * @param code
     * @return
     */
    @GetMapping("/weibo/success")
    public String weiboSuccess(String code, HttpSession session) {
        log.info("weiboSuccess code is {}", code);
        Map<String, String> map = new HashMap<>();
        Map<String, String> headers = new HashMap<>();
        map.put("client_id", appKey);
        map.put("client_secret", appSecret);
        map.put("code", code);
        map.put("grant_type", "authorization_code");
        map.put("redirect_uri", "http://auth.grainmall.cn/oauth/weibo/success");
        String body = null;
        try {
            HttpResponse response = HttpUtils.doPost("https://api.weibo.com", "/oauth2/access_token", "post", headers, map, body);
            if (response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                String json = EntityUtils.toString(entity);
                log.info("call weibo /oauth2/access_token, response content is {}", json);

                WeiboUser user = JSON.parseObject(json, WeiboUser.class);
                map.clear();
                map.put("access_token", user.getAccess_token());
                map.put("uid", user.getUid());
                map.put("code", code);
                response = HttpUtils.doGet("https://api.weibo.com", "/2/users/show.json", "get", headers, map);
                if (response.getStatusLine().getStatusCode() == 200) {
                    entity = response.getEntity();
                    json = EntityUtils.toString(entity);
                    log.info("call weibo /2/users/show.json, response content is {}", json);
                    WeiboUserDetail userDetail = JSON.parseObject(json, WeiboUserDetail.class);
                    user.setName(userDetail.getName());
                    user.setGender(userDetail.getGender());
                    user.setHeader(userDetail.getAvatar_large());
                }
                R r = memberFeignService.oauthLogin(user);
                MemberTo data = r.getData(new TypeReference<MemberTo>(){});
                log.debug("", data);
                session.setAttribute(AuthServerConstant.USER_SESSION_KEY, data);
            }
        } catch (Exception e) {
            log.error("error in weiboSuccess ", e);
        }

        return "redirect:http://grainmall.cn";
    }

    @GetMapping("/weibo/fail")
    public String fail() {
        return "";
    }
}
